package com.guanzhi.TimeClass;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 小工具
 * <p> Package: com.guanzhi.TimeClass </p>
 * <p> File: DateCalculationUtil.java </p>
 * <p> Description:  (时间类型-计算)</p>
 * <p> Date: 2023/3/22 11:19</p>
 *
 * @author 观之
 * @version 1.0 （代码版本）
 * @email <a href="mailto:guanzhi55634@aliyun.com">观之</a>（邮箱）
 * @since JDK11（JDK版本）
 */
public class DateCalculationUtil {
    /**
     * 获取几个月前某天的时间
     *
     * @param nowTime     当前时间
     * @param beforeMonth 前几个月 负数 过大会倒推或前进年份
     * @param dayOfMonth  那天
     * @return 日期
     * @throws ParseException 异常捕获
     */
    public static String getMonthBefore(String nowTime, int beforeMonth, int dayOfMonth) throws ParseException {

        // 获取当前时间 不用时分秒 HH:mm:ss
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = dateFormat.parse(nowTime);

        if (beforeMonth > 0) {
            return null;
        }

        //获取当前年份
        int year = getYear(date);
        //获取当前月份天数
        int monthHowManyDays = getMonthHowManyDays(year, dayOfMonth);
        //设置取某月天数范围
        if (dayOfMonth >= 1 && dayOfMonth <= monthHowManyDays) {
            //得到日历
            Calendar calendar = Calendar.getInstance();
            //把当前时间赋给日历
            calendar.setTime(date);
            //设置为前2月，可根据需求进行修改
            calendar.add(Calendar.MONTH, beforeMonth);
            //设置上月26号
            calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
            //获取2个月前的时间
            date = calendar.getTime();
            return dateFormat.format(date);
        }
        return null;
    }

    /**
     * 获取某年某月有多少天
     *
     * @param year  年份
     * @param month 月份
     * @return 多少天
     */
    public static int getMonthHowManyDays(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, 1);
        calendar.add(Calendar.DATE, -1);
        return calendar.get(Calendar.DATE);
    }

    /**
     * 拆分日期
     *
     * @param date 时间
     * @return 返回拆分结果
     */
    public static Map<String, Integer> splitDate(Date date) {
        //拆分后的时间
        Map<String, Integer> splitMap = new HashMap<>();

        //拆出年份
        int year = Integer.parseInt(String.format("%tY", date));
        //拆出月份
        int month = Integer.parseInt(String.format("%tm", date));
        //拆出日期
        int day = Integer.parseInt(String.format("%td", date));
        //拆出小时
        int hour = Integer.parseInt(String.format("%tH", date));
        //拆出分钟
        int minute = Integer.parseInt(String.format("%tM", date));
        //拆除秒数
        int second = Integer.parseInt(String.format("%tS", date));

        splitMap.put("year", year);
        splitMap.put("month", month);
        splitMap.put("day", day);
        splitMap.put("hour", hour);
        splitMap.put("minute", minute);
        splitMap.put("second", second);

        return splitMap;
    }

    /**
     * 获取年份
     *
     * @param date 时间
     * @return 年份
     */
    public static int getYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取月份
     *
     * @param date 时间
     * @return 月份
     */
    public static int getMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 根据两个时间获取相差的月数
     *
     * @param startDate 日期起期
     * @param endDate   日期止期
     * @return 相差月份
     */
    public static int getMonth(Date startDate, Date endDate) {
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        startCalendar.setTime(startDate);
        endCalendar.setTime(endDate);

        int year1 = startCalendar.get(Calendar.YEAR);
        int year2 = endCalendar.get(Calendar.YEAR);

        int month1 = startCalendar.get(Calendar.MONTH);
        int month2 = endCalendar.get(Calendar.MONTH);

        int day1 = startCalendar.get(Calendar.DAY_OF_MONTH);
        int day2 = endCalendar.get(Calendar.DAY_OF_MONTH);
        // 获取年的差值
        int yearInterval = year1 - year2;
        // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
        if (month1 < month2 || month1 == month2 && day1 < day2) {
            yearInterval--;
        }
        // 获取月数差值
        int monthInterval = (month1 + 12) - month2;
        if (day1 < day2) {
            monthInterval--;
        }
        monthInterval %= 12;
        return Math.abs(yearInterval * 12 + monthInterval);
    }

    /**
     * 根据两个时间获取相差的月数
     *
     * @param startDate 日期起期
     * @param endDate   日期止期
     * @return 相差月份
     */
    public static int getMonth(String startDate, String endDate) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        Date sDate = dateFormat.parse(startDate);
        Date eDate = dateFormat.parse(endDate);
        return getMonth(sDate, eDate);
    }

    /**
     * 获取天份
     *
     * @param date 时间
     * @return 天份
     */
    public static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DATE);
    }

    /**
     * 获取小时
     *
     * @param date 时间
     * @return 小时
     */
    public static int getDayOfHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 获取分钟
     *
     * @param date 时间
     * @return 分钟
     */
    public static int getDayOfMinute(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 获取秒
     *
     * @param date 时间
     * @return 秒
     */
    public static int getDayOfSecond(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }
}
